﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 飞机大战
{
    public partial class Form1 : Form
    {
        private Background _background;
        private Plane _myPlane;
        private Image[] _backgroudImages = { Resource1.bg, Resource1.boss, Resource1.e7, Resource1.plane };
        private Image[] _myPlaneAndShellImgs = { Resource1.plane, Resource1.shell };
        private Image[] _enemyPlaneImgs = { Resource1.enemy1 };
        private Image[] _enemyPlane2AndShellImgs = { Resource1.enemy2, Resource1.enemy2bullet };
        private Image[] _littleBoss1AndShellImgs = { Resource1.littleboss1, Resource1.littleboss1bullet };
        private Image[] _littleBoss2AndShellImgs = { Resource1.littleboss2, Resource1.littleboss2bullet };
        private Image[] _bossAndShellImgs = { Resource1.boss, Resource1.bossbullet };
        private Image[] _explodeImages = {Resource1.e1, Resource1.e2, Resource1.e3, Resource1.e4,
        Resource1.e5,Resource1.e6,Resource1.e7,Resource1.e8};
        private Shell _myPlaneShell;
        private List<Shell> _myPlaneShellList = new List<Shell>();
        private List<Shell> _delMyPlaneShellList = new List<Shell>();
        private Random _rnd = new Random();
        private List<Plane> _enemyPlane1List = new List<Plane>();
        private List<Plane> _delEnemyPlane1List = new List<Plane>();
        private Dictionary<Plane, List<Shell>> _enemyPlane2AndShells = new Dictionary<Plane, List<Shell>>();
        private Dictionary<Plane, List<Shell>> _littleBoss1AndShells = new Dictionary<Plane, List<Shell>>();
        private Dictionary<Plane, List<Shell>> _littleBoss2AndShells = new Dictionary<Plane, List<Shell>>();
        private List<Plane> _delEnemyPlaneList = new List<Plane>();
        private List<Shell> _bossPlaneShellList = new List<Shell>();
        private List<Shell> _delBossPlaneShellList = new List<Shell>();
        private Plane _bossPlane;
        private Graphics _graphics;
        private GameScore _gameScore;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _background = new Background(0, 0, Width, Height, _backgroudImages, 0, State.NoGameStarted);
            _myPlane = new Plane(this.Width / 2, this.Height / 2, 40, 50, _myPlaneAndShellImgs, 0, State.GameStarted, 6);
            _graphics = this.CreateGraphics();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            //画背景
            _background.Draw(e.Graphics);

            if (_background.State == State.GameStarted)
            {
                //画我方飞机和子弹
                #region
                //画我方飞机
                _myPlane.Draw(e.Graphics);

                //获取我方飞机的每一个子弹
                foreach (Shell myShell in _myPlaneShellList)
                {
                    //画我方子弹
                    myShell.Draw(e.Graphics);
                    //判断我方飞机子弹是否越界
                    if (_myPlaneShell.Y < 0)
                    {
                        _delMyPlaneShellList.Add(myShell);
                    }
                }

                //获取每个我方飞机需要被清除的子弹
                foreach (Shell delShell in _delMyPlaneShellList)
                {
                    //清除多余的子弹对象
                    _myPlaneShellList.Remove(delShell);
                }
                //清空我方飞机越界的子弹数量
                _delMyPlaneShellList.Clear();

                //Console.WriteLine("我方飞机子弹数量: " + _myPlaneShellList.Count);
                #endregion
                //画敌方飞机1
                #region
                foreach (Plane enemyPlane1 in _enemyPlane1List)
                {
                    enemyPlane1.Draw(e.Graphics);
                    //将越界的敌机1放入到对应集合中
                    if (enemyPlane1.Y < 0)
                    {
                        _delEnemyPlane1List.Add(enemyPlane1);
                    }
                }
                foreach (Plane delEnemyPlane1 in _delEnemyPlane1List)
                {
                    //删除越界的敌机1
                    _enemyPlane1List.Remove(delEnemyPlane1);
                }
                _delEnemyPlane1List.Clear();
                //Console.WriteLine("敌方飞机1的数量: " + _enemyPlane1List.Count);
                #endregion
                //画敌方飞机2和对应子弹
                DrawEnemyPlaneAndShell(_enemyPlane2AndShells, e.Graphics);

                //画Boss1飞机和对应子弹
                DrawEnemyPlaneAndShell(_littleBoss1AndShells, e.Graphics);

                //画Boss2飞机和对应子弹
                DrawEnemyPlaneAndShell(_littleBoss2AndShells, e.Graphics);

                //画Boss飞机和子弹
                if (_bossPlane != null)
                {
                    _bossPlane.DrawBoss(e.Graphics, this.Width);
                    foreach (Shell bossPlaneShell in _bossPlaneShellList)
                    {
                        bossPlaneShell.Draw(e.Graphics);
                        //判断boss子弹是否越界
                        if (bossPlaneShell.Y > this.Height)
                        {
                            _delBossPlaneShellList.Add(bossPlaneShell);
                        }
                    }
                }
            }
            else if(_background.State == State.GameEnded)
            {
                
            }

        }

        private void DrawEnemyPlaneAndShell(Dictionary<Plane, List<Shell>> enemyPlanesAndShells, Graphics graphics)
        {
            foreach (Plane enemyPlane in enemyPlanesAndShells.Keys)
            {
                //画敌机
                enemyPlane.Draw(graphics);

                //获取到敌机的子弹集合
                List<Shell> enemyPlaneShellList = enemyPlanesAndShells[enemyPlane];
                foreach (Shell enemyPlaneShell in enemyPlaneShellList)
                {
                    enemyPlaneShell.Draw(graphics);
                }

                //判断敌机是否越界
                if (enemyPlane.Y >= this.Height)
                {
                    _delEnemyPlaneList.Add(enemyPlane);
                }
            }

            //删除越界敌机和子弹集合
            foreach (Plane delEnemyPlanes in _delEnemyPlaneList)
            {
                //清除敌机子弹集合
                if (enemyPlanesAndShells.ContainsKey(delEnemyPlanes))
                {
                    enemyPlanesAndShells[delEnemyPlanes].Clear();
                }
                //清除敌机
                enemyPlanesAndShells.Remove(delEnemyPlanes);
            }
            _delEnemyPlaneList.Clear();
        }

        private void Form1_Click(object sender, EventArgs e)
        {
            if (_background.State == State.NoGameStarted)
            {
                //隐藏光标
                Cursor.Hide();

                _background = new Background(0, -this.Height, this.Width, this.Height * 2, _backgroudImages, 3, State.GameStarted);
                //背景移动
                Background_Timer.Interval = 40;
                Background_Timer.Start();

                //生产我方飞机子弹
                MyPlaneShellTimer.Interval = 300;
                MyPlaneShellTimer.Start();

                //生产敌方飞机1
                EnemyPlane1Timer.Interval = 900;
                EnemyPlane1Timer.Start();

                //生产敌方飞机2
                EnemyPlane2Timer.Interval = 4000;
                EnemyPlane2Timer.Start();

                //生产敌机2子弹
                EnemyPlane2ShellTimer.Interval = 500;
                EnemyPlane2ShellTimer.Start();

                //生产Boss1飞机
                LittleBoss1Timer.Interval = 10000;
                LittleBoss1Timer.Start();

                //生产Boss1飞机子弹
                LittleBoss1ShellTimer.Interval = 1000;
                LittleBoss1ShellTimer.Start();

                //生产Boss2飞机
                LitteleBoss2Timer.Interval = 16000;
                LitteleBoss2Timer.Start();

                //生产boss2飞机子弹
                LittleBoss2ShellTimer.Interval = 1500;
                LittleBoss2ShellTimer.Start();

                //生产Boss飞机
                BossTimer.Interval = 3000;
                BossTimer.Start();

                //生产boss飞机子弹
                BossShellTimer.Interval = 1600;
                BossShellTimer.Start();

                //检测碰撞
                CheckTimer.Interval = 150;
                CheckTimer.Start();
            }
        }

        private void Background_Tick(object sender, EventArgs e)
        {
            this.Invalidate();
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (_background.State == State.GameStarted)
            {
                if(_myPlane.X < this.Width)
                {
                    _myPlane.X = e.X - _myPlane.Width / 2;
                    _myPlane.Y = e.Y - _myPlane.Height / 2;
                }
            }
        }

        private void MyPlaneShellTimer_Tick(object sender, EventArgs e)
        {
            if (_background.State == State.GameStarted)
            {
                //创建我方飞机子弹
                _myPlaneShell = new Shell(_myPlane.X + 14, _myPlane.Y - 29, 14, 29, _myPlaneAndShellImgs, 10, State.MyPlane);
                //将我方飞机子弹加添到集合
                _myPlaneShellList.Add(_myPlaneShell);

            }
        }

        private void EnemyPlane1Timer_Tick(object sender, EventArgs e)
        {
            if (_background.State == State.GameStarted)
            {
                //创建敌方飞机1
                Plane enemyPlane1 = new Plane(_rnd.Next(0, this.Width - Resource1.enemy1.Width), 0, 32, 24, _enemyPlaneImgs, 6, State.EnemyPlane, 0);

                //将敌方飞机1添加到集合中
                _enemyPlane1List.Add(enemyPlane1);
            }
        }

        private void EnemyPlane2Timer_Tick(object sender, EventArgs e)
        {
            if (_background.State == State.GameStarted)
            {
                //创建敌方飞机2
                Plane enemyPlane2 = new Plane(_rnd.Next(0, this.Width - Resource1.enemy2.Width), 0, 44, 67, _enemyPlane2AndShellImgs, 4, State.EnemyPlane, 1);
                //创建敌机2子弹集合
                List<Shell> enemyPlane2Shells = new List<Shell>();
                //将敌方飞机2添加到集合中
                _enemyPlane2AndShells.Add(enemyPlane2, enemyPlane2Shells);
            }
        }

        private void EnemyPlane2ShellTimer_Tick(object sender, EventArgs e)
        {
            if (_background.State == State.GameStarted)
            {
                //为敌方飞机2添加子弹
                //获取到每个敌机
                foreach (Plane enemyPlane2 in _enemyPlane2AndShells.Keys)
                {
                    List<Shell> enemyPlane2ShellList = _enemyPlane2AndShells[enemyPlane2];
                    enemyPlane2ShellList.Add(new Shell(enemyPlane2.X + 14, enemyPlane2.Y + 60, 14, 25, _enemyPlane2AndShellImgs, 11, State.EnemyPlane));
                }
            }

        }

        private void LittleBoss1Timer_Tick(object sender, EventArgs e)
        {
            if (_background.State == State.GameStarted)
            {
                //创建Boss1飞机
                Plane boss1 = new Plane(_rnd.Next(0, this.Width - Resource1.littleboss1.Width), 0, 172, 112, _littleBoss1AndShellImgs, 2, State.EnemyPlane, 8);
                //创建Boss1的子弹集合
                List<Shell> boss1Shells = new List<Shell>();
                //将Boss1添加到集合中
                _littleBoss1AndShells.Add(boss1, boss1Shells);
            }
        }

        private void LittleBoss1ShellTimer_Tick(object sender, EventArgs e)
        {
            if (_background.State == State.GameStarted)
            {
                //为Boss1子弹集合
                //获取到每个Boss1
                foreach (Plane littleBoss1 in _littleBoss1AndShells.Keys)
                {
                    List<Shell> littleBossShellList = _littleBoss1AndShells[littleBoss1];
                    littleBossShellList.Add(new Shell(littleBoss1.X + 75, littleBoss1.Y + 110, 25, 26, _littleBoss1AndShellImgs, 8, State.EnemyPlane));
                    Console.WriteLine($"Boss1的子弹x :{littleBoss1.X}, Y:{littleBoss1.Y}");
                }
            }
        }

        private void LitteleBoss2Timer_Tick(object sender, EventArgs e)
        {
            if (_background.State == State.GameStarted)
            {
                //创建Boss2飞机
                Plane boss2 = new Plane(_rnd.Next(0, this.Width - Resource1.littleboss2.Width), 0, 172, 112, _littleBoss2AndShellImgs, 2, State.EnemyPlane, 8);
                //创建Boss2的子弹集合
                List<Shell> boss2Shells = new List<Shell>();
                //将Boss2添加到集合中
                _littleBoss2AndShells.Add(boss2, boss2Shells);
            }
        }

        private void LittleBoss2ShellTimer_Tick(object sender, EventArgs e)
        {
            //为Boss2子弹集合
            //获取到每个Boss1
            foreach (Plane littleBoss2 in _littleBoss2AndShells.Keys)
            {
                List<Shell> littleBossShellList = _littleBoss2AndShells[littleBoss2];
                littleBossShellList.Add(new Shell(littleBoss2.X + 75, littleBoss2.Y + 110, 21, 59, _littleBoss2AndShellImgs, 8, State.EnemyPlane));
                Console.WriteLine($"Boss1的子弹x :{littleBoss2.X}, Y:{littleBoss2.Y}");
            }
        }

        private void BossTimer_Tick(object sender, EventArgs e)
        {
            //创建Boss飞机
            _bossPlane = new Plane(_rnd.Next(0, this.Width - Resource1.boss.Width), 0, 240, 174, _bossAndShellImgs, 2, State.Boss, 10);
            //停止计时器
            BossTimer.Stop();
        }

        private void BossShellTimer_Tick(object sender, EventArgs e)
        {
            if (_bossPlane != null)
            {
                Shell bossShell = new Shell(_bossPlane.X + 85, _bossPlane.Y + 180, 51, 72, _bossAndShellImgs, 6, State.EnemyPlane);
                _bossPlaneShellList.Add(bossShell);
            }

        }

        private void CheckTimer_Tick(object sender, EventArgs e)
        {
            Check();
        }

        //检测碰撞
        private void Check()
        {
            //1.我方飞机子弹和敌方飞机检测
            foreach (Shell myPlaneShell in _myPlaneShellList)
            {
                //检测我方飞机子弹是否与敌机1碰撞
                DestoryMyPlaneShellAndEnemyPlane(myPlaneShell, _enemyPlane1List, null);

                //检测我方飞机子弹是否与敌机2碰撞
                DestoryMyPlaneShellAndEnemyPlane(myPlaneShell, null, _enemyPlane2AndShells);

                //检测我方飞机子弹是否与littleBoss1碰撞
                DestoryMyPlaneShellAndEnemyPlane(myPlaneShell, null, _littleBoss1AndShells);

                //检测我方飞机子弹是否与littleBoss2碰撞
                DestoryMyPlaneShellAndEnemyPlane(myPlaneShell, null, _littleBoss2AndShells);

                //检测我方飞机子弹是否与Boss碰撞
                if (_bossPlane != null)
                {
                    if (myPlaneShell.GetRectangle().IntersectsWith(_bossPlane.GetRectangle()))
                    {
                        if (_bossPlane.Life > 0)
                        {
                            _bossPlane.Life--;
                            myPlaneShell.Y = -2000;
                        }
                        else
                        {
                            Explode explode = new Explode(_bossPlane.X, _bossPlane.Y, _explodeImages);
                            explode.DrawExplode(_graphics);
                            myPlaneShell.Y = -2000;
                            _bossPlane.X = 3000;
                            _bossPlaneShellList.Clear();
                            GameOver();
                        }
                    }
                }
            }

            ////2.我方飞机和敌方飞机或子弹碰撞
            ////检测我方飞机是否与敌机1碰撞
            //DestoryMyPlane(_enemyPlane1List, null);

            ////检测我方飞机是否与敌机2或其子弹碰撞
            //DestoryMyPlane(null, _enemyPlane2AndShells);

            ////检测我方飞机是否与littleBoss1或其子弹碰撞
            //DestoryMyPlane(null, _littleBoss1AndShells);

            ////检测我方飞机是否与littleBoss2或其子弹碰撞
            //DestoryMyPlane(null, _littleBoss2AndShells);

            ////检测我方飞机是否与BOSS或其子弹碰撞
            //if (_bossPlane != null)
            //{
            //    if (_myPlane.GetRectangle().IntersectsWith(_bossPlane.GetRectangle()))
            //    {
            //        CheckMyplaneLife();
            //    }
            //    foreach (Shell bossPlaneShell in _bossPlaneShellList)
            //    {
            //        if (bossPlaneShell.GetRectangle().IntersectsWith(_myPlane.GetRectangle()))
            //        {
            //            CheckMyplaneLife();
            //        }
            //    }
            //}
        }
        private void DestoryMyPlaneShellAndEnemyPlane(Shell myPlaneShell, List<Plane> enemyPlaneList, Dictionary<Plane, List<Shell>> enemyPlaneAndShells)
        {
            if (enemyPlaneList != null)
            {
                foreach (Plane enemyPlane in enemyPlaneList)
                {
                    if (myPlaneShell.GetRectangle().IntersectsWith(enemyPlane.GetRectangle()))
                    {
                        if (enemyPlane.Life > 0)
                        {
                            enemyPlane.Life--;
                            myPlaneShell.Y = -2000;
                        }
                        else
                        {
                            Explode explode = new Explode(enemyPlane.X - 10, enemyPlane.Y - 10, _explodeImages);
                            explode.DrawExplode(_graphics);
                            myPlaneShell.X = -2000;
                            enemyPlane.X = 2000;
                        }

                    }
                }
            }

            if (enemyPlaneAndShells != null)
            {
                foreach (Plane enemyPlane in enemyPlaneAndShells.Keys)
                {
                    if (myPlaneShell.GetRectangle().IntersectsWith(enemyPlane.GetRectangle()))
                    {
                        if (enemyPlane.Life > 0)
                        {
                            enemyPlane.Life--;
                            myPlaneShell.Y = -2000;
                        }
                        else
                        {
                            Explode explode = new Explode(enemyPlane.X - 10, enemyPlane.Y - 10, _explodeImages);
                            explode.DrawExplode(_graphics);
                            myPlaneShell.Y = -2000;
                            enemyPlane.X = 3000;
                            enemyPlaneAndShells[enemyPlane].Clear();
                        }
                    }
                }
            }
        }
        private void DestoryMyPlane(List<Plane> enemyPlaneList, Dictionary<Plane, List<Shell>> enemyPlaneAndShells)
        {
            if (enemyPlaneList != null)
            {
                foreach (Plane enemyPlane in enemyPlaneList)
                {
                    if (_myPlane.GetRectangle().IntersectsWith(enemyPlane.GetRectangle()))
                    {
                        CheckMyplaneLife();
                    }
                }
            }

            if (enemyPlaneAndShells != null)
            {
                foreach (Plane enemyPlane in enemyPlaneAndShells.Keys)
                {
                    if (_myPlane.GetRectangle().IntersectsWith(enemyPlane.GetRectangle()))
                    {
                        CheckMyplaneLife();
                    }
                    List<Shell> enemyPlaneShells = enemyPlaneAndShells[enemyPlane];
                    foreach (Shell enemyShell in enemyPlaneShells)
                    {
                        if (_myPlane.GetRectangle().IntersectsWith(enemyShell.GetRectangle()))
                        {
                            CheckMyplaneLife();
                        }
                    }
                }
            }
        }
        private void CheckMyplaneLife()
        {
            if (_myPlane.Life > 0)
            {
                _myPlane.Life--;
            }
            else
            {
                _myPlane.Y = -6000;
                _myPlaneShellList.Clear();
                GameOver();
            }
        }

        private void GameOver()
        {
            Cursor.Show();
            _background.State = State.GameEnded;
            if(_bossPlane.Life > 0)
            {
                MessageBox.Show("游戏结束");
            }
            else
            {
                MessageBox.Show("恭喜你胜利了");

            }
        }
    }

}
